package com.qst.controller;

import com.qst.pojo.dto.CreateOrderDTO;
import com.qst.pojo.entity.Order;
import com.qst.pojo.entity.OrderItem;
import com.qst.pojo.entity.Station;
import com.qst.pojo.entity.StationInventory;
import com.qst.pojo.entity.InventoryHistory;
import com.qst.repository.OrderItemRepository;
import com.qst.repository.StationRepository;
import com.qst.repository.StationInventoryRepository;
import com.qst.repository.InventoryHistoryRepository;
import com.qst.service.OrderService;
import com.qst.util.JwtUtil;
import com.qst.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 订单控制器
 */
@RestController
@RequestMapping("/api/orders")
public class OrderController {

    private static final Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private OrderService orderService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private OrderItemRepository orderItemRepository;
    
    @Autowired
    private StationRepository stationRepository;
    
    @Autowired
    private StationInventoryRepository stationInventoryRepository;
    
    @Autowired
    private InventoryHistoryRepository inventoryHistoryRepository;

    /**
     * 获取我的订单（客户端）
     */
    @GetMapping("/my")
    public Result<List<Map<String, Object>>> getMyOrders(
            @RequestHeader(value = "Authorization", required = false) String token,
            @RequestParam(required = false) String status) {
        try {
            // 检查token是否存在
            if (token == null || token.trim().isEmpty()) {
                logger.error("获取我的订单失败: Authorization token为空");
                return Result.error("未登录或登录已过期，请重新登录");
            }
            
            // 从token中获取用户ID
            String jwtToken = token.replace("Bearer ", "").trim();
            Integer customerId = jwtUtil.getUserIdFromToken(jwtToken);
            
            if (customerId == null) {
                logger.error("从token中获取用户ID失败");
                return Result.error("无法获取用户信息，请重新登录");
            }
            
            // 获取客户的订单列表
            Map<String, Object> result = orderService.getCustomerOrders(customerId, status, 1, 1000);
            List<Map<String, Object>> orders = (List<Map<String, Object>>) result.get("list");
            
            return Result.success(orders);
        } catch (io.jsonwebtoken.ExpiredJwtException e) {
            logger.error("JWT token已过期", e);
            return Result.error("登录已过期，请重新登录");
        } catch (io.jsonwebtoken.JwtException e) {
            logger.error("JWT token解析失败", e);
            return Result.error("登录信息无效，请重新登录");
        } catch (Exception e) {
            logger.error("获取我的订单失败", e);
            return Result.error("获取订单列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取订单列表（支持按客户ID筛选）
     */
    @GetMapping
    public Result<Map<String, Object>> getAllOrders(
            @RequestParam(required = false) Integer customerId,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            // 如果提供了customerId，则获取该客户的订单
            if (customerId != null) {
                Map<String, Object> result = orderService.getCustomerOrders(customerId, status, page, pageSize);
                return Result.success(result);
            } else {
                // 否则返回所有订单
                List<Order> orders = orderService.getAllOrders();
                return Result.success(Map.of("list", orders, "total", orders.size()));
            }
        } catch (Exception e) {
            logger.error("获取订单列表失败", e);
            return Result.error("获取订单列表失败");
        }
    }

    /**
     * 根据ID获取订单
     */
    @GetMapping("/{id}")
    public Result<Map<String, Object>> getOrderById(@PathVariable Integer id) {
        try {
            Map<String, Object> orderDetail = orderService.getOrderDetail(id);
            return Result.success(orderDetail);
        } catch (Exception e) {
            logger.error("获取订单详情失败", e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 创建订单（新版本，使用DTO）
     */
    @PostMapping
    public Result<Map<String, Object>> createOrder(
            @RequestBody CreateOrderDTO createOrderDTO,
            @RequestHeader("Authorization") String token) {
        try {
            // 从token中获取用户ID
            String jwtToken = token.replace("Bearer ", "");
            Integer customerId = jwtUtil.getUserIdFromToken(jwtToken);
            
            if (customerId == null) {
                return Result.error("无法获取用户信息");
            }
            
            Map<String, Object> result = orderService.createOrderFromDTO(createOrderDTO, customerId);
            return Result.success("订单创建成功", result);
        } catch (Exception e) {
            logger.error("创建订单失败", e);
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 创建订单（旧版本，保留兼容性）
     */
    @PostMapping("/legacy")
    public Result<Order> createOrderLegacy(@RequestBody Order order) {
        try {
            Order createdOrder = orderService.createOrder(order);
            return Result.success("订单创建成功", createdOrder);
        } catch (Exception e) {
            logger.error("创建订单失败", e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 更新订单状态
     */
    @PatchMapping("/{id}/status")
    public Result<Order> updateOrderStatus(@PathVariable Integer id, @RequestBody Map<String, String> request) {
        try {
            String statusStr = request.get("status");
            if (statusStr == null) {
                return Result.error("状态参数缺失");
            }

            Order.OrderStatus newStatus;
            try {
                newStatus = Order.OrderStatus.valueOf(statusStr);
            } catch (IllegalArgumentException e) {
                return Result.error("无效的状态值");
            }

            Order updatedOrder = orderService.updateOrderStatus(id, newStatus);
            return Result.success("订单状态更新成功", updatedOrder);
        } catch (Exception e) {
            logger.error("更新订单状态失败", e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 更新订单
     */
    @PutMapping("/{id}")
    public Result<Order> updateOrder(@PathVariable Integer id, @RequestBody Order order) {
        try {
            Order existingOrder = orderService.getOrderById(id);
            
            // 更新订单信息
            if (order.getPickupAddress() != null) {
                existingOrder.setPickupAddress(order.getPickupAddress());
            }
            if (order.getPickupTime() != null) {
                existingOrder.setPickupTime(order.getPickupTime());
            }
            if (order.getTotalAmount() != null) {
                existingOrder.setTotalAmount(order.getTotalAmount());
            }
            if (order.getTotalWeight() != null) {
                existingOrder.setTotalWeight(order.getTotalWeight());
            }
            if (order.getNotes() != null) {
                existingOrder.setNotes(order.getNotes());
            }
            
            // 如果状态改变，使用 updateOrderStatus 方法（会发送通知）
            if (order.getStatus() != null && !order.getStatus().equals(existingOrder.getStatus())) {
                Order updatedOrder = orderService.updateOrderStatus(id, order.getStatus());
                return Result.success("订单更新成功", updatedOrder);
            }
            
            return Result.success("订单更新成功", existingOrder);
        } catch (Exception e) {
            logger.error("更新订单失败", e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取站点订单列表
     */
    @GetMapping("/station/{stationId}")
    public Result<Map<String, Object>> getStationOrders(
            @PathVariable Integer stationId,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            Map<String, Object> result = orderService.getStationOrders(stationId, status, page, pageSize);
            return Result.success(result);
        } catch (Exception e) {
            logger.error("获取站点订单失败", e);
            return Result.error("获取站点订单失败: " + e.getMessage());
        }
    }

    /**
     * 获取订单统计信息
     */
    @GetMapping("/stats")
    public Result<Map<String, Object>> getOrderStats(
            @RequestParam Integer stationId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        try {
            LocalDate start = startDate != null ? LocalDate.parse(startDate) : LocalDate.now();
            LocalDate end = endDate != null ? LocalDate.parse(endDate) : LocalDate.now();
            
            Map<String, Object> stats = orderService.getOrderStats(stationId, start, end);
            return Result.success(stats);
        } catch (Exception e) {
            logger.error("获取订单统计失败", e);
            return Result.error("获取订单统计失败: " + e.getMessage());
        }
    }

    /**
     * 确认订单
     */
    @PatchMapping("/{id}/confirm")
    public Result<Order> confirmOrder(@PathVariable Integer id, @RequestBody Map<String, Object> request) {
        try{
            Order order = orderService.getOrderById(id);
            
            // 更新为已确认状态
            order.setStatus(Order.OrderStatus.confirmed);
            
            // 如果提供了实际取货时间
            if (request.containsKey("actualPickupTime")) {
                String timeStr = (String) request.get("actualPickupTime");
                order.setActualPickupTime(java.time.LocalDateTime.parse(timeStr.substring(0, 19)));
            }
            
            // 如果提供了备注，直接更新（不追加）
            if (request.containsKey("notes")) {
                String newNotes = (String) request.get("notes");
                order.setNotes(newNotes);
            }
            
            Order updatedOrder = orderService.updateOrderStatus(id, Order.OrderStatus.confirmed);
            return Result.success("订单确认成功", updatedOrder);
        } catch (Exception e) {
            logger.error("确认订单失败", e);
            return Result.error("确认订单失败: " + e.getMessage());
        }
    }

    /**
     * 开始处理订单
     */
    @PatchMapping("/{id}/start-processing")
    public Result<Order> startProcessing(@PathVariable Integer id, @RequestBody Map<String, Object> request) {
        try {
            Order order = orderService.getOrderById(id);
            
            // 如果提供了实际取货时间
            if (request.containsKey("actualPickupTime")) {
                String timeStr = (String) request.get("actualPickupTime");
                order.setActualPickupTime(java.time.LocalDateTime.parse(timeStr.substring(0, 19)));
            }
            
            Order updatedOrder = orderService.updateOrderStatus(id, Order.OrderStatus.in_progress);
            return Result.success("订单已开始处理", updatedOrder);
        } catch (Exception e) {
            logger.error("开始处理订单失败", e);
            return Result.error("开始处理订单失败: " + e.getMessage());
        }
    }

    /**
     * 完成订单
     */
    @PatchMapping("/{id}/complete")
    @Transactional
    public Result<Order> completeOrder(@PathVariable Integer id, @RequestBody Map<String, Object> request) {
        try {
            // 1. 获取订单信息
            Order order = orderService.getOrderById(id);
            Integer stationId = order.getStationId();
            
            // 2. 获取订单物品明细
            List<OrderItem> orderItems = orderItemRepository.findByOrderId(id);
            
            // 3. 将订单物品入库到站点库存
            for (OrderItem orderItem : orderItems) {
                Integer itemId = orderItem.getItemId();
                Integer quantity = orderItem.getQuantity();
                
                // 查找或创建库存记录
                StationInventory inventory = stationInventoryRepository
                        .findByStationIdAndItemId(stationId, itemId)
                        .orElseGet(() -> {
                            StationInventory newInventory = new StationInventory();
                            newInventory.setStationId(stationId);
                            newInventory.setItemId(itemId);
                            newInventory.setQuantity(BigDecimal.ZERO);
                            newInventory.setMinStock(BigDecimal.valueOf(10));
                            newInventory.setMaxStock(BigDecimal.valueOf(100));
                            return newInventory;
                        });
                
                BigDecimal beforeQuantity = inventory.getQuantity();
                BigDecimal addQuantity = new BigDecimal(quantity);
                BigDecimal afterQuantity = beforeQuantity.add(addQuantity);
                
                // 更新库存
                inventory.setQuantity(afterQuantity);
                stationInventoryRepository.save(inventory);
                
                // 4. 记录库存历史
                InventoryHistory history = new InventoryHistory();
                history.setStationId(stationId);
                history.setItemId(itemId);
                history.setOperationType("add");
                history.setBeforeQuantity(beforeQuantity);
                history.setChangeQuantity(addQuantity);
                history.setAfterQuantity(afterQuantity);
                history.setReason("订单完成自动入库 - 订单号: " + order.getOrderNo());
                history.setOperator("系统自动");
                inventoryHistoryRepository.save(history);
            }
            
            // 5. 更新站点的当前负载
            updateStationLoad(stationId);
            
            // 6. 更新订单状态为已完成
            Order updatedOrder = orderService.updateOrderStatus(id, Order.OrderStatus.completed);
            
            return Result.success("订单已完成，物品已入库", updatedOrder);
        } catch (Exception e) {
            logger.error("❌ 完成订单失败: orderId={}", id, e);
            return Result.error("完成订单失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新站点的当前负载
     */
    private void updateStationLoad(Integer stationId) {
        try {
            List<StationInventory> inventoryList = stationInventoryRepository.findByStationId(stationId);
            BigDecimal totalLoad = inventoryList.stream()
                    .map(StationInventory::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            stationRepository.findById(stationId).ifPresent(station -> {
                station.setCurrentLoad(totalLoad.intValue());
                stationRepository.save(station);
            });
        } catch (Exception e) {
            logger.error("更新站点负载失败: stationId={}", stationId, e);
        }
    }

    /**
     * 取消订单
     */
    @PatchMapping("/{id}/cancel")
    public Result<Order> cancelOrder(@PathVariable Integer id, @RequestBody Map<String, String> request) {
        try {
            String reason = request.get("reason");
            Order order = orderService.getOrderById(id);
            
            // 直接设置取消原因为备注（不追加）
            if (reason != null && !reason.isEmpty()) {
                order.setNotes("取消原因: " + reason);
            }
            
            Order updatedOrder = orderService.updateOrderStatus(id, Order.OrderStatus.cancelled);
            return Result.success("订单已取消", updatedOrder);
        } catch (Exception e) {
            logger.error("取消订单失败", e);
            return Result.error("取消订单失败: " + e.getMessage());
        }
    }
}


